/**
 * PEmpreendimento.java
 * Copyright (C) 2009 Jose Mauro da Silva Sandy
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package persistencia.pessoas;

import java.io.IOException;
import java.sql.*;
import plagio.postgres.ConnectionPostgres;
import negocio.pessoas.Empreendimento;
import java.util.*;
import utils.*;

/**
 *
 * @author jmsandy
 */
public class PEmpreendimento {

    //<editor-fold defaultstate="collapsed" desc="Attributes">
    private boolean error = false;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Acessores">
    public boolean isError(){
        return this.error;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Table Columns">
    static final protected String K_TBL_Empreendimento   = "Empreendimento";
    static final protected String K_COL_cod_objeto       = "cod_objeto";
    static final protected String K_COL_status           = "status";
    static final protected String K_COL_dataInicio       = "datainicio";
    static final protected String K_COL_dataTermPrevisto = "datatermprevisto";
    static final protected String K_COL_dataTermEfetivo  = "datatermefetivo";
    static final protected String K_COL_dtVenda          = "dtvenda";
    static final protected String K_COL_valorVenda       = "valorvenda";
    static final protected String K_COL_pessoa           = "pessoa";
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    /**
     * Construtor padrao. Responsavel por realizar a persistencia
     * de um Empreendimento
     * @throws java.io.IOException
     */
    public PEmpreendimento() throws IOException{
        error = false;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Methods">
    // Realiza a construcao basica de um select
    private StringBuilder formSelector(){
        StringBuilder query = new StringBuilder();
        query.append("SELECT " + K_COL_cod_objeto + ", " + K_COL_status + ", ");
        query.append(K_COL_dataInicio + ", " + K_COL_dataTermEfetivo + ", ");
        query.append(K_COL_dataTermPrevisto + ", " + K_COL_dtVenda + ", ");
        query.append(K_COL_valorVenda + ", " + K_COL_pessoa + " FROM ");
        query.append("\"" + K_TBL_Empreendimento + "\"");
        return query;
    }

    /**
     * Responsavel por criar a estrutura para inserir o objeto
     * @return construtor do objeto a ser inserido
     */
    public String formInsert(){
        return "INSERT INTO \"" + K_TBL_Empreendimento + "\"(" +
                K_COL_cod_objeto + ", " + K_COL_status + ", " +
                K_COL_dataInicio + ", " + K_COL_dataTermPrevisto + ", " +
                K_COL_dataTermEfetivo + ", " + K_COL_dtVenda + ", " +
                K_COL_valorVenda + ", " + K_COL_pessoa + ") VALUES " + 
                "(?, ?, ?, ?, ?, ?, ?, ?)";
    }

    /**
     * Responsavel por criar a estrutura para atualizar o objeto
     * @param obj - Objeto a ser atualizado na base de dados
     * @return construtor do objeto a ser atualizado
     */
    public String formUpdate(Empreendimento obj){
        StringBuilder query = new StringBuilder();
        query.append("UPDATE \"" + K_TBL_Empreendimento + "\" SET ");
        query.append(K_COL_status + " = '" + obj.getStatus() + "', ");
        query.append(K_COL_valorVenda + " = '" + obj.getValorVenda() + "'");
        query.append(obj.getDataInicio() != null ? 
        (" , " + K_COL_dataInicio + " = '"  + obj.getDataInicio() + "' "): "");
        query.append(obj.getDataTermPrevisto() != null ? 
        (" , " + K_COL_dataTermPrevisto + " = '"  + obj.getDataTermPrevisto() + 
                                                                    "' "): "");
        query.append(obj.getDataTermEfetivo() != null ? 
        (" , " + K_COL_dataTermEfetivo + " = '"  + obj.getDataTermEfetivo() + 
                                                                    "' "): "");        
        query.append(obj.getDtVenda()!= null ? 
        (" , " + K_COL_dtVenda + " = '"  + obj.getDtVenda() + "' "): "");
        query.append(" WHERE " + K_COL_cod_objeto +  " = '");
        query.append(obj.getCod_objeto() + "'");

        return query.toString();
    }

    /**
     * Responsavel por criar a estrutura para deletar o objeto
     * @param obj - Objeto a ser deletado na base de dados
     * @return construtor do objeto a ser deletado
     */
    public String formDelete(Empreendimento obj){
        return "DELETE FROM \"" + K_TBL_Empreendimento + "\" WHERE " +
                K_COL_cod_objeto + " = '" + obj.getCod_objeto() + "'";
    }

    /**
     * Responsavel por inserir um objeto na base de dados
     * @param obj - objeto a ser inserido na base de dados
     * @return TRUE - caso afirmativo e FALSE - caso contrario
     */
    public Boolean insert(Empreendimento obj){
        Boolean status = true;

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();
            PreparedStatement stat;
            String query = formInsert();
            stat = conn.getConnection().prepareStatement(query);
            stat.setString(1, obj.getCod_objeto());
            stat.setInt(2, obj.getStatus());
            stat.setDate(3, new java.sql.Date(obj.getDataInicio().getTime()));
            stat.setDate(4, new java.sql.Date(obj.getDataTermPrevisto().getTime()));
            stat.setDate(5, new java.sql.Date(obj.getDataTermEfetivo().getTime()));
            stat.setDate(6, new java.sql.Date(obj.getDtVenda().getTime()));
            stat.setDouble(7, obj.getValorVenda());
            stat.setString(8, obj.getPessoa());
            stat.executeUpdate();
            stat.close();
            conn.closeConnection();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            status = false;
        }
        return status;
    }

    /**
     * Responsavel por atualizar um objeto na base de dados
     * @param obj - objeto a ser atualizado na base de dados
     * @return TRUE - caso afirmativo e FALSE - caso contrario
     */
    public Boolean update(Empreendimento obj){
        Boolean status = true;

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            // Monta o objeto em uma instrucao SQL para atualizacao no banco
            PreparedStatement stat;
            String query = formUpdate(obj);
            stat = conn.getConnection().prepareStatement(query);
            stat.executeUpdate();
            stat.close();
            conn.closeConnection();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            status = false;
        }
        return status;
    }

    /**
     * Responsavel por deletar um objeto na base de dados
     * @param obj - objeto a ser deletado na base de dados
     * @return TRUE - caso afirmativo e FALSE - caso contrario
     */
    public Boolean delete(Empreendimento obj){
        Boolean status = true;

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            // Monta o objeto em uma instrucao SQL para atualizacao no banco
            PreparedStatement stat;
            String query = formDelete(obj);
            stat = conn.getConnection().prepareStatement(query);
            stat.executeUpdate();
            stat.close();
            conn.closeConnection();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            status = false;
        }
        return status;
    }

    /**
     * Recupera um objeto empreendimento pelo codigo fornecido
     * @param cod_objeto codigo do empreendimento a ser procurado
     * @return o empreendimento encontrado ou NULL
     */
    public Empreendimento refresh(String cod_objeto){
        Empreendimento emp = new Empreendimento(); // objeto de retorno

        StringBuilder query = this.formSelector();
        // Clausula where
        query.append(" WHERE " + K_COL_cod_objeto + " = '" + cod_objeto + "'");

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            Statement stat = conn.getConnection().createStatement();

            // Verifica a existencia do registro de retorno
            ArrayList<Empreendimento> lstEmp = new ArrayList<Empreendimento>();
            lstEmp = mapear(stat.executeQuery(query.toString()));
            if(lstEmp.size() > 0) emp = lstEmp.get(0);
            else emp = null;

        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            emp = null;
        }
        return emp;
    }

    /**
     * Recupera um objeto empreendimento relacionado a uma pessoa
     * @param idPessoa identificador da pessoa relacionada ao empreendimento
     * @return o empreendimento encontrado ou NULL
     */
    public Empreendimento recEmpreendimentoPessoa(String idPessoa){
        Empreendimento emp = new Empreendimento(); // objeto de retorno

        StringBuilder query = this.formSelector();
        // Clausula where
        query.append(" WHERE " + K_COL_pessoa + " = '" + idPessoa + "'");

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            Statement stat = conn.getConnection().createStatement();

            // Verifica a existencia do registro de retorno
            ArrayList<Empreendimento> lstEmp = new ArrayList<Empreendimento>();
            lstEmp = mapear(stat.executeQuery(query.toString()));
            if(lstEmp.size() > 0) emp = lstEmp.get(0);
            else emp = null;

        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            emp = null;
        }
        return emp;
    }

    /**
     * Recupera uma lista de empreendimentos que satifasca uma dada situacao
     * @param situacao situacao a ser procurada
     * @return lista de empreendimentos
     */
    public ArrayList<Empreendimento> recLstEmprendimentos(int situacao){
        // Lista de objetos de retorno
        ArrayList<Empreendimento> lstEmp = new ArrayList<Empreendimento>();

        StringBuilder query = this.formSelector();
        // Clausula where
        query.append(" WHERE " + K_COL_status + " = " + situacao);
        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            Statement stat = conn.getConnection().createStatement();
            lstEmp =  mapear(stat.executeQuery(query.toString()));
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            lstEmp = null;
        }
        return lstEmp;
    }

    /**
     * Realiza a soma de todas as despesas de um empreendimento
     * @param idEmp identificador do empreendimento
     * @return soma das despesas de um empreendimento
     */
    public Double sumGastos(String idEmp){
        Double sum = 0.0;

        StringBuilder query = new StringBuilder();
        query.append("SELECT SUM(VALORNOTA) FROM \"Nota\" WHERE empreendimento");
        query.append(" = '" + idEmp + "'");
        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            Statement stat = conn.getConnection().createStatement();
            ResultSet rs = stat.executeQuery(query.toString());
            if(rs.next()){
                sum = rs.getDouble(1);
            }
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            sum = 0.0;
        }

        return sum;
    }

    /**
     * Responsavel por converter o objeto vindo do banco de dados para um
     * modelo de objeto
     * @param result - result que obtem toda lista recebida do servidor
     * @return os objetos mapeados
     * @throws java.sql.SQLException
     */
    private ArrayList<Empreendimento> mapear(ResultSet result) throws SQLException{
        ArrayList<Empreendimento> lstEmp = new ArrayList<Empreendimento>();

        // Converte todo result recebido para uma lista de objetos
        while(result.next()){
            Empreendimento emp = new Empreendimento();
            emp.setCod_objeto(result.getString(1));
            emp.setStatus(result.getInt(2));
            emp.setDataInicio(result.getDate(3));
            emp.setDataTermEfetivo(result.getDate(4));
            emp.setDataTermPrevisto(result.getDate(5));
            emp.setDtVenda(result.getDate(6));
            emp.setValorVenda(result.getDouble(7));
            emp.setPessoa(result.getString(8));
            emp.setIsNew(false);

            lstEmp.add(emp);
        }
        return lstEmp;
    }
    //</editor-fold>
}